package com.shopping.service.store;

import com.alibaba.fastjson.JSONObject;
import com.shopping.constant.ResponseCode;
import com.shopping.dao.CollectionDao;
import com.shopping.dao.RetailRoleDao;
import com.shopping.dao.StoreDao;
import com.shopping.dao.TradeDao;
import com.shopping.pojo.Collection;
import com.shopping.pojo.RetailRole;
import com.shopping.pojo.Store;
import com.shopping.pojo.Trade;
import com.shopping.util.CheckUtil;
import com.shopping.util.DetectMarksUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class StoreServiceImpl implements StoreService {

    @Autowired
    StoreDao storeDao;
    @Autowired
    CollectionDao collectionDao;
    @Autowired
    RetailRoleDao retailRoleDao;
    @Autowired
    TradeDao tradeDao;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    JSONObject json = new JSONObject();

    @Override
    public Map<String, Object> registerStore(int userId, String idNumber, Store store) {
        Map<String, Object> map = new HashMap<>();
        if(!CheckUtil.checkIdCard(idNumber)){
            map.put("code", ResponseCode.PARAM_ERROR.getValue());
            return map;
        }
        RetailRole retailRole;
        try{
//            store.setStoreName(DetectMarksUtil.replaceMarks(store.getStoreName()));
            storeDao.insert(store);
            int storeId = storeDao.lastInsertId();
            store.setId(storeId);
//            stringRedisTemplate.opsForValue().set("store" + store.getStoreName(), json.toJSONString(store));
            stringRedisTemplate.opsForHash().put("store", store.getStoreName(), json.toJSONString(store));
            retailRole = new RetailRole();
            retailRole.setId(userId);
            retailRole.setIdNumber(idNumber);
            retailRole.setStoreId(storeId);

            retailRoleDao.insert(retailRole);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("store", storeDao.selectOneByName(store.getStoreName()));
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> selectByName(String storeName) {
        Map<String, Object> map = new HashMap<>();
        try {
//            storeName = DetectMarksUtil.replaceMarks(storeName);
            Store redisStore = null;
//            redisStore = json.parseObject(stringRedisTemplate.opsForValue().get("store" + storeName), Store.class);
            redisStore = json.parseObject(String.valueOf(stringRedisTemplate.opsForHash().get("store", storeName)), Store.class);
            if(redisStore != null){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("store", redisStore);
            }
            redisStore = storeDao.selectOneByName(storeName);
            if(redisStore != null){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("store", redisStore);
            } else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showAllStores() {
        Map<String, Object> map = new HashMap<>();
        try {
            Map<Object , Object> storeMap = stringRedisTemplate.opsForHash().entries("store");
            List<Store> stores = new ArrayList<>();
            Iterator<Map.Entry<Object, Object>> entryIterator = storeMap.entrySet().iterator();
            while(entryIterator.hasNext()){
                Map.Entry<Object, Object> entry = entryIterator.next();
                stores.add(json.parseObject(String.valueOf(entry.getValue()), Store.class));
            }
//            stores = storeDao.selectAll();
            if(stores.size() != 0){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("stores", stores);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showStoreByName(String storeName) {
        Map<String, Object> map = new HashMap<>();
        try {
//            storeName = DetectMarksUtil.replaceMarks(storeName);
            List<Store> stores = storeDao.selectByName(storeName);
            if(stores.size() != 0){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("stores", stores);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showStoreById(int id) {
        Map<String, Object> map = new HashMap<>();
        Store store = null;
        try{
//            Map<Object , Object> storeMap = stringRedisTemplate.opsForHash().entries("store");
//            Iterator<Map.Entry<Object, Object>> entryIterator = storeMap.entrySet().iterator();
//            while(entryIterator.hasNext()){
//                Map.Entry<Object, Object> entry = entryIterator.next();
//                if(json.parseObject(String.valueOf(entry.getValue()), Store.class).getId() == id){
//                    store = json.parseObject(String.valueOf(entry.getValue()), Store.class);
//                    break;
//                }
//            }
            store = json.parseObject(String.valueOf(stringRedisTemplate.opsForHash().get("store", storeDao.selectStoreNameById(id))), Store.class);
            if(store == null){
                store = storeDao.selectById(id);
            }
            if(store != null){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("store", store);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> exchangeStoreName(int storeId, String name) {
        Map<String, Object> map = new HashMap<>();
        try{
//            name = DetectMarksUtil.replaceMarks(name);
            Store store = storeDao.selectById(storeId);
            stringRedisTemplate.opsForHash().delete("store", store.getStoreName());
            storeDao.updateName(storeId, name);
            store.setStoreName(name);
            stringRedisTemplate.opsForHash().put("store", store.getStoreName(), json.toJSONString(store));
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("store", store);
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> exchangeStoreAvatar(int storeId, byte[] avatar) {
        Map<String, Object> map = new HashMap<>();
        try{
            storeDao.updateAvatar(storeId, avatar);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("store", storeDao.selectById(storeId));
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> updateGrade(int storeId) {
        Map<String, Object> map = new HashMap<>();
        try{
            storeDao.updateLevel(storeId);
            stringRedisTemplate.opsForHash().increment("store", storeDao.selectStoreNameById(storeId), 1);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> addFans(int storeId, int fansId) {
        Map<String, Object> map = new HashMap<>();
        try{
            storeDao.updateFans(storeId);
            stringRedisTemplate.opsForHash().increment("store", storeDao.selectStoreNameById(storeId), 1);

            Collection collection = new Collection();
            collection.setType(1);
            collection.setId(storeId);
            collection.setUserId(fansId);

            collectionDao.insert(collection);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showAllTrade(int storeId) {
        Map<String, Object> map = new HashMap<>();
        try{
            List<Trade> trades = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + storeId), Trade.class);
//            List<Trade> trades = tradeDao.selectByStoreId(storeId);
            if(trades.size() != 0){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("trades", trades);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> selectStoreIdByUserId(int userId) {
        Map<String, Object> map = new HashMap<>();
        int storeId = -1;
        try{
            storeId = retailRoleDao.selectStoreId(userId);
            map.put("storeId", storeId);
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

}
